﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Maestro_Proveedores.clases.almacen
{
    class RegLinealSimple : ModeloAbstracto
    {
        ArrayList resultadosN;
        double a, b;

        //-------------------------CONSTRUCTOR DE CLASE
        public RegLinealSimple()
        {
            this.nombreModelo = "Regresión Lineal Simple";
            this.registros = new ArrayList();
            this.resultadosN = new System.Collections.ArrayList();
            resNideal = new Resultado();
            a = 0;
            b = 0;
        }

        //------------------------ INICIO METODOS SOBREESCRITOS

        public override Resultado obtenerResultado()
        {
            return this.resNideal;
        }

        public override void pronosticoSemanaN()
        {
            semanaPronostico = registros.Count+1;
            resNideal.pronosticoN1 = a + b * semanaPronostico;
        }

        public override void calcularModelo(System.Collections.ArrayList registrosF)
        {
            this.registros = registrosF;
            // se evalua que existan mas de 52 datos de pronostico..
            if (registros.Count >= 53)
            {
                //valor promedio para los valores de x Semana 1 a la Semana 45 
                double mediaX = 23;
                //valor promedio de la demanada
                double mediaY = promedioDemanda(45);
                //variables sumatorias
                double xmediax=0;
                double ymediay=0;
                double Sxx = 0;
                double Syy= 0;
                double Sxy = 0;
                foreach (Registro reg in registros) {
                    if (reg.Semana <= 45){
                        xmediax =reg.Semana - mediaX;
                        ymediay = reg.Demanda - mediaY;
                        Sxx += Math.Pow(xmediax, 2);
                        Syy += Math.Pow(ymediay, 2);
                        Sxy += xmediax * ymediay;
                    }
                    else
                        break;
                }
                //calculo variables iniciales
                b = Sxy/Sxx;
                a = mediaY-b*mediaX;

                foreach (Registro reg in registros)
                {
                    if (reg.Semana > 45)
                    {
                        // calculo del pronostico
                        reg.Pronostico = a+b*reg.Semana;
                        //se calcula el et
                        reg.Et = reg.Demanda - reg.Pronostico;
                        //se calcula el etabsoluto
                        reg.Etabsoluto = Math.Abs(reg.Et);
                        //se calcula el etcuadrado
                        reg.Etcuadrado = Math.Pow(reg.Et, 2);
                        //se calcula el APE
                        reg.Ape = 100 * (Math.Abs(reg.Et / reg.Demanda));
                        //se calcula el APE1
                        reg.Ape1 = 100 * (Math.Abs(reg.Et / reg.Pronostico));

                    }
                    
                }

                //calculan los resultados ET, ETabsoluto, Etcuadrado
                resNideal = calcularResultados(registros);
                resNideal.RegistrosFinal = registros;
                // se calcula el pronostico para la siguiente semana (N+1) se al macena en el resNIDEal
                pronosticoSemanaN();
                //this.mostrarArreglo("ReglinealSimple");
            }
            else
            {
                // el archivo no tiene minimo 53 semanas
                System.Windows.Forms.MessageBox.Show("Debe cargar minimo 53 Semanas");
            }


        }

        //------------------------ FIN METODOS SOBREESCRITOS

        // funcion para calcular el promedio de la semana n
        private double promedioDemanda(int semana)
        {
            double sum = 0;
            double prom = 0;
            foreach (Registro reg in registros)
            {
                if (reg.Semana <= semana)
                {
                    sum += reg.Demanda;
                }
                else
                    break;
            }
            prom = sum / semana;
            return prom;
        }

        private Resultado calcularResultados(ArrayList registros)
        {
            Resultado resultado = new Resultado();

            double sumatoriaMAD = 0;
            double sumatoriaECM = 0;
            double sumatoriaMAPE = 0;
            double sumatoriaMAPE1 = 0;
            double count = 0;

            foreach (Registro reg in registros)
            {
                if (reg.Pronostico != 0)
                {
                    sumatoriaMAD += reg.Etabsoluto;
                    sumatoriaECM += reg.Etcuadrado;
                    sumatoriaMAPE += reg.Ape;
                    sumatoriaMAPE1 += reg.Ape1;
                    count++;
                }
            }

            resultado.ECM = sumatoriaECM / count;
            resultado.MAD = sumatoriaMAD / count;
            resultado.MAPE = sumatoriaMAPE / count;
            resultado.MAPE1 = sumatoriaMAPE1 / count;

            return resultado;
        }

        public void mostrarArreglo(String nombre)
        {
        //    Gestion_Inventario_Proveedores.clases.herramientas.FileManager file = new Gestion_Inventario_Proveedores.clases.herramientas.FileManager();
        //    file.generarArchivo(registros, nombre);
        }
        
    }
}
